package io.gitee.xjt2016.modules.service.sys;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
import io.gitee.xjt2016.modules.common.utils.CookieUtils;
import io.gitee.xjt2016.modules.domain.sys.Role;
import io.gitee.xjt2016.modules.domain.sys.User;
import io.gitee.xjt2016.modules.mapper.sys.UserMapper;
import io.gitee.xjt2016.modules.security.LoginFilter;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class UserService extends ServiceImpl<UserMapper, User> {

    @Resource
    RoleService roleService;

    @Resource
    RedisTemplate<String, Object> redisTemplate;

    public User findByUsername(String username) {
        if (StringUtils.isBlank(username)) {
            return null;
        }
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username);
        return this.getOne(queryWrapper);
    }

    public Set<Role> findRoleList(String username) {
        User user = findByUsername(username);
        if (user == null) {
            return new HashSet<>();
        }
        return Sets.newHashSet(roleService.listByIds(user.getRoleIdList()));
    }

    public boolean login(String username, String password, HttpServletResponse response) {
        User user = findByUsername(username);
        if (user == null) {
            throw new RuntimeException("用户不存在：" + username);
        }
        if (!Objects.equals(user.getPassword(), password)) {
            throw new RuntimeException("密码不正确：" + username);
        }
        String key = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(key, user, LoginFilter.COOKIE_EXPIRE_TIME, TimeUnit.SECONDS);
        CookieUtils.set(response, LoginFilter.COOKIE_KEY, key, LoginFilter.COOKIE_EXPIRE_TIME);
        return true;
    }

    public boolean checkLogin(HttpServletRequest request) {
        Cookie cookie = CookieUtils.get(request, LoginFilter.COOKIE_KEY);
        String key = cookie.getValue();
        if (StringUtils.isBlank(key)) {
            return false;
        }
        Preconditions.checkNotNull(key);
        Object o = redisTemplate.opsForValue().get(key);
        return o != null;
    }

    public void logout(HttpServletRequest request, HttpServletResponse response) {
        Cookie cookie = CookieUtils.get(request, LoginFilter.COOKIE_KEY);
        String key = cookie.getValue();
        if (checkLogin(request)) {
            redisTemplate.delete(key);
        }
        CookieUtils.set(response, LoginFilter.COOKIE_KEY, null, 0);
    }

    /**
     * 根据用户名查找其角色
     *
     * @param username
     * @return
     */
    public Set<String> findRoles(String username) {
        User user = findByUsername(username);
        if (user == null) {
            return Collections.EMPTY_SET;
        }
        return roleService.findRoles(user.getRoleIdList().toArray(new Long[0]));
    }

    /**
     * 根据用户名查找其权限
     *
     * @param username
     * @return
     */
    public Set<String> findPermissions(String username) {
        User user = findByUsername(username);
        if (user == null) {
            return Collections.EMPTY_SET;
        }
        return roleService.findPermissions(user.getRoleIdList().toArray(new Long[0]));
    }

}

